package sii.challenge.predictors;

import sii.challenge.dataset.Dataset;

/**
 * 
 * Predittore che combina lo UserBasedPredictor al SimplePredictor,
 * usando il primo solo quando ci sono molti dati a disposizione.
 * 
 * @author Marco Liceti
 *
 */
public final class MyPredictor implements Predictor {
	
	private static int alpha = 100;
	private static int beta = 150;
	
	private Dataset dataset;
	private Predictor simple_predictor;
	private Predictor user_based_predictor;
	
	private static MyPredictor instance;
	
	private MyPredictor(Dataset dataset) {
		this.dataset = dataset;
		simple_predictor = SimplePredictor.getInstance(dataset);
		user_based_predictor = UserBasedPredictor.getInstance(dataset);
	}
	
	/**
	 * 
	 * Restituisce un nuovo MyPredictor.
	 * 
	 * @param dataset l'istanza di Dataset necessaria al predittore
	 * 
	 * @return un nuovo oggetto MyPredictor
	 * 
	 */
	public static MyPredictor getInstance(Dataset dataset) {
		if (instance == null) {
			instance = new MyPredictor(dataset);
		}
		return instance;
	}

	@Override
	public int predictRating(int user, int item) {
		int number_ratings_from_user = dataset.getNumberOfRatingsFromUser(user);
		int number_ratings_for_item = dataset.getNumberOfRatingsForItem(item);
		
		if (number_ratings_from_user >= alpha && number_ratings_from_user <= beta && number_ratings_for_item >= alpha && number_ratings_for_item <= beta) {
			int rating = user_based_predictor.predictRating(user, item);
			if (rating < 0) {
				return simple_predictor.predictRating(user, item);
			}
		}

		return simple_predictor.predictRating(user, item);
	}

}
